package org.example.mrrope.utils;

import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Decription:
 * 通用方法
 *
 * @author hzk
 * @Date 2021/10/21 17:45
 */
public class CusutUtil {


    //当前时间加几天返回
    public static String SetTimeAddDay(int day) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, day);
        return sf.format(c.getTime());
    }

    //当前时间加几月返回
    public static String SetTimeAddMonth(int Month) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, Month);
        return sf.format(c.getTime());
    }

    //月份加任意
    public static String monthAddFrist(String date, int month) {

        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Calendar ct = Calendar.getInstance();
            ct.setTime(df.parse(date));
            ct.add(Calendar.MONTH, month);
            return df.format(ct.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    //时间转时间戳(yyyy年MM月dd日) 毫秒级
    public static long dateTOtimeshap(String date) {
        String date_str = date +  " 00:00:00";
        DateFormat df = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        try {

            Date time = df.parse(date_str);
            long timestamp = time.getTime();
            return timestamp;
        } catch (Exception e) {
            try {
                Date  time = df.parse(date);
                long timestamp = time.getTime();
                return timestamp;
            } catch (ParseException parseException) {
                parseException.printStackTrace();
            }

        }
        return 0;
    }

    //时间转时间戳(yyyyMMdd) 毫秒级
    public static long dateTOtimeshapYYMMDD(String date) {
        date += " 00:00:00";
        DateFormat df = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
        try {

            Date time = df.parse(date);
            long timestamp = time.getTime();
            return timestamp;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    //时间转格式(yyyy/MM/dd/)
    public static String dateTOxieg(String date) {
        return date.replace("年", "").replace("月", "").replace("日", "");
    }

    //天数加任意
    public static String DayAddFrist(String date, int day) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Calendar ct = Calendar.getInstance();
            ct.setTime(df.parse(date));
            ct.add(Calendar.DAY_OF_MONTH, day);
            return df.format(ct.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    //根据云枢url获取refId
    public static String ByUrlGetRefId(String url) {
        String refId = url.substring(url.indexOf("?") + 7, url.indexOf("&"));
        return refId;
    }

    //String to html
    public static String strToHtml(String s) {
        if (s == null || s.equals("")) return "";
        s = s.replaceAll("&amp;", "&");
        s = s.replaceAll("&lt;", "<");
        s = s.replaceAll("&gt;", ">");
        s = s.replaceAll("  ", "&nbsp;");
        return s;
    }

    //从头开始删除字符的方法
    public static String TruncateHeadString(String origin, int count) {
        if (origin == null || origin.length() < count) {
            return null;
        }
        char[] arr = origin.toCharArray();
        char[] ret = new char[arr.length - count];
        for (int i = 0; i < ret.length; i++) {
            ret[i] = arr[i + count];
        }

        return String.copyValueOf(ret);
    }

    //从尾部开始删除字符的方法
    public static String TruncateTailString(String origin, int count) {
        if (origin == null || origin.length() < count) {
            return null;
        }
        char[] arr = origin.toCharArray();
        char[] ret = new char[arr.length - count + 1];
        for (int i = 0; i < ret.length; i++) {
            ret[i] = arr[i];
        }

        return String.copyValueOf(ret);
    }

    /**
     * 获取现在时间
     *
     * @return 返回时间类型 yyyy-MM-dd HH:mm:ss
     */
    public static String getNowDate() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    /**
     * @param string
     * @return 转换之后的内容
     * @Title: unicodeDecode
     * @Description: unicode解码 将Unicode的编码转换为中文
     */
    public static String unicodeDecode(String string) {
        Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
        Matcher matcher = pattern.matcher(string);
        char ch;
        while (matcher.find()) {
            ch = (char) Integer.parseInt(matcher.group(2), 16);
            string = string.replace(matcher.group(1), ch + "");
        }
        return string;
    }


    /**
     * 获取现在时间 -格式
     *
     * @return 返回时间类型 yyyyMMdd
     */
    public static String getNowDate(String gs) {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(gs);
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    //时间戳转时间 yyyyMMdd
    public static String getFormatDate(long times) {
        Date date = new Date(times);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        String dateString = formatter.format(date);
        return dateString;
    }

    //时间戳转时间 yyyyMMdd
    public static String getFormatDateYY(long times) {
        Date date = new Date(times);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy");
        String dateString = formatter.format(date);
        return dateString;
    }

    //时间戳转时间 yyyyMM
    public static String getFormatDateMM(long times) {
        Date date = new Date(times);
        SimpleDateFormat formatter = new SimpleDateFormat("MM");
        String dateString = formatter.format(date);
        return dateString;
    }

    /**
     * 获取现在时间 -带时区
     *
     * @return 返回时间类型 yyyy-MM-dd'T'HH:mm:ssXXX
     */
    public static String getNowDate_TIMEZONE() {
        Date currentTime = new Date();

        Calendar cal = Calendar.getInstance(); // creates calendar

        cal.setTime(currentTime); // sets calendar time/date

        cal.add(Calendar.HOUR_OF_DAY, 2); // adds one hour

        currentTime = cal.getTime();//
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
        String dateString = formatter.format(currentTime);
        return dateString;
    }


    //获取jayy数组
    public static JSONArray getJayy(String s) {
        JSONObject jObj = new JSONObject(s);
        JSONArray content = new JSONArray();
        if (jObj.has("data")) {
            JSONObject jdata = new JSONObject(jObj.get("data").toString());
            content = new JSONArray(jdata.get("content").toString());
        }
        return content;
    }

    //月份加1
    public static String monthAddFrist(String date) {

        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Calendar ct = Calendar.getInstance();
            ct.setTime(df.parse(date));
            ct.add(Calendar.MONTH, +1);
            return df.format(ct.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    //返回成功格式
    public static String SuccessReturnJsonString(int code, String data, String... types) {
        for (String type : types) {
            if (type.toLowerCase().contains("str")) data = "\"" + data + "\"";
        }
        return "{\"code\":" + code + ",\"message\":\"\",\"response\":" + data + ",\"success\":true}";
    }


    public static Object jsonByHas(JSONObject jo, String key) {
        if (jo.has(key)) {
            return jo.get(key);
        }
        return null;
    }

    //返回失败格式
    public static String ErrorReturnJsonString(int code, String message, String... types) {
        if (types.length == 0) {
            message = "\"" + message + "\"";
        }
        return "{\"code\":" + code + ",\"message\":" + message + ",\"response\":null,\"success\":false}";
    }

    //返回json中需要的参
    public static String getJsonValue(JSONObject iter, String jpath) {
        String[] json_vals = jpath.split("\\.");
        for (int i = 0; i < json_vals.length; i++) {
            if (i + 1 >= json_vals.length)
                return iter.has(json_vals[i]) ? iter.get(json_vals[i]).toString() : "";

            iter = new JSONObject(iter.get(json_vals[i]).toString());
        }

        return "";
    }


    //计算两个时间相差的秒数
    public static long getTime(String startTime, String endTime) {
        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            long eTime = df.parse(endTime).getTime();
            long sTime = df.parse(startTime).getTime();
            long diff = (eTime - sTime) / 1000;
            return diff;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return 0;
    }


    /**
     * 生成32位随机数
     *
     * @return
     */
    public static String random32() {
        Random rand = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 1; i <= 32; i++) {
            int randNum = rand.nextInt(9) + 1;
            String num = randNum + "";
            sb = sb.append(num);
        }
        String random = String.valueOf(sb);
        return random;
    }

    //转义字符供getJsonValue使用
    private static String tpath = "data.%s.";

    public static String getJpath(String Name) {
        return getJpath("", Name);
    }

    public static String getJpath(String Name, String params) {
        return String.format(tpath, params) + Name;
    }

    //获取前端发送的json字符串
    public static String getPostString(HttpServletRequest request) {
        String s = "";

        InputStream in = null;

        BufferedInputStream bin = null;

        try {
            in = request.getInputStream();

            bin = new BufferedInputStream(in);

            int len = 0;

            byte[] b = new byte[1024];

            while ((len = bin.read(b)) != -1) {
                s += new String(b, 0, len);

            }

        } catch (IOException e) {
            e.printStackTrace();

        } finally {
            try {
                bin.close();

            } catch (IOException e) {
                e.printStackTrace();

            }

            try {
                in.close();

            } catch (IOException e) {
                e.printStackTrace();

            }
            return s;
        }
    }

    //Authorization
    public static HttpEntity<String> JsonToHttpEntity(JSONObject json, String... Authorization) {
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        if (Authorization.length > 0) {
            headers.add("Authorization", Authorization[0]);
        }
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        HttpEntity<String> formEntity = new HttpEntity<String>(json.toString(), headers);
        return formEntity;
    }


    public static HttpEntity<String> HttpEntity_headers(JSONObject json, HashMap<String, String> map) {
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        if (map.size() > 0) {
            for (Map.Entry entry : map.entrySet()) {
                headers.add(entry.getKey().toString(), entry.getValue().toString());
            }
        }
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        HttpEntity<String> formEntity = new HttpEntity<String>(json.toString(), headers);
        return formEntity;
    }
    //加密方法

    /**
     * 传入文本内容，返回 SHA-256 串
     *
     * @param strText
     * @return
     */
    public static String SHA256(final String strText) {
        return SHA(strText, "SHA-256");
    }

    /**
     * 传入文本内容，返回 SHA-512 串
     *
     * @param strText
     * @return
     */
    public static String SHA512(final String strText) {
        return SHA(strText, "SHA-512");
    }

    /**
     * 字符串 SHA 加密
     *
     * @param strType
     * @return
     */
    private static String SHA(final String strText, final String strType) {
        // 返回值
        String strResult = null;

        // 是否是有效字符串
        if (strText != null && strText.length() > 0) {
            try {
                // SHA 加密开始
                // 创建加密对象 并傳入加密類型
                MessageDigest messageDigest = MessageDigest.getInstance(strType);
                // 传入要加密的字符串
                messageDigest.update(strText.getBytes());
                // 得到 byte 類型结果
                byte byteBuffer[] = messageDigest.digest();

                // 將 byte 轉換爲 string
                StringBuffer strHexString = new StringBuffer();
                // 遍歷 byte buffer
                for (int i = 0; i < byteBuffer.length; i++) {
                    String hex = Integer.toHexString(0xff & byteBuffer[i]);
                    if (hex.length() == 1) {
                        strHexString.append('0');
                    }
                    strHexString.append(hex);
                }
                // 得到返回結果
                strResult = strHexString.toString();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
        }

        return strResult;
    }

    //用户密码加密封装
    public static String hash_password(String password) {
        return SHA256(SHA512(password));
    }

    public static String md5(String body) {
        String md5 = "";
        try {
            md5 = DigestUtils.md5DigestAsHex(body.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return md5;
    }

    /**
     * 去除前后指定字符
     *
     * @param args   目标字符串
     * @param beTrim 要删除的指定字符
     * @return 删除之后的字符串
     * 调用示例：System.out.println(trim("$$abc $","$"));
     */
    public static String trim(String args, char beTrim) {
        int st = 0;
        int len = args.length();
        char[] val = args.toCharArray();
        char sbeTrim = beTrim;
        while ((st < len) && (val[st] <= sbeTrim)) {
            st++;
        }
        while ((st < len) && (val[len - 1] <= sbeTrim)) {
            len--;
        }
        return ((st > 0) || (len < args.length())) ? args.substring(st, len) : args;
    }

    /**
     * MultipartFile 转 File
     *
     * @param file
     * @throws Exception
     */
    public static File multipartFileToFile(MultipartFile file) throws Exception {

        File toFile = null;
        if (file.equals("") || file.getSize() <= 0) {
            file = null;
        } else {
            InputStream ins = null;
            ins = file.getInputStream();
            toFile = new File(new Date().getTime() + "-" + UUID.randomUUID() + "." + file.getOriginalFilename().split("\\.")[1]);
            inputStreamToFile(ins, toFile);
            ins.close();
        }
        return toFile;
    }

    //获取流文件
    private static void inputStreamToFile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除本地临时文件
     *
     * @param file
     */
    public static void delteTempFile(File file) {
        if (file != null) {
            File del = new File(file.toURI());
            del.delete();
        }
    }


    /**
     * 根据经纬度查询
     *
     * @param log
     * @param lat
     * @return
     */
    public static String getAdd(String log, String lat) {
        //lat 小  log  大
        //参数解释: 纬度,经度 type 001 (100代表道路，010代表POI，001代表门址，111可以同时显示前三项)
        String urlString = "http://api.map.baidu.com/geocoder/v2/?ak=0EXAjYp9hii1DrK3Tuda8efu9vivslcX&callback=renderReverse&location=" + lat + "," + log + "&output=json&pois=1";
        String res = "";
        try {
            URL url = new URL(urlString);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoOutput(true);
            conn.setRequestMethod("POST");
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                res += line + "\n";
            }
            in.close();
        } catch (Exception e) {
            System.out.println("error in wapaction,and e is " + e.getMessage());
        }
        System.out.println(res);
        return res;
    }


    public static void main(String[] args) {
        /*  System.out.println(getAdd(119.0478515625+"",31.5785354265+""));*/
        //System.out.println(addressResolution("河南省仙桃市"));
        double b = (double) 560 / 100;
        System.out.println(b);
        String add = CusutUtil.getAdd("119.0478515625", "31.5785354265");
        System.out.println(add);
    }

    /**
     * 根据url 拉取文件
     *
     * @param url
     * @return
     * @throws Exception
     */
    public static File getFile(String url) throws Exception {
        File file = null;
        try {
            HttpURLConnection httpUrl = (HttpURLConnection) new URL(url).openConnection();
            httpUrl.connect();
            file = CusutUtil.inputStreamToFile(httpUrl.getInputStream(), "url.png");
            httpUrl.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return file;
    }

    /**
     * 工具类
     * inputStream 转 File
     */
    public static File inputStreamToFile(InputStream ins, String name) throws Exception {
        File file = new File(System.getProperty("java.io.tmpdir") + File.separator + name);
        if (file.exists()) {
            return file;
        }
        OutputStream os = new FileOutputStream(file);
        int bytesRead;
        int len = 8192;
        byte[] buffer = new byte[len];
        while ((bytesRead = ins.read(buffer, 0, len)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        os.close();
        ins.close();
        return file;
    }


    public static String isJson(String str) {
        String result = "false";
        if (str != null) {
            str = str.trim();
            if (str.startsWith("{") && str.endsWith("}")) {
                result = "json";
            } else if (str.startsWith("[") && str.endsWith("]")) {
                result = "jarray";
            }
        }
        return result;
    }

    public static String jsonTOxml(JSONObject jo) {
        Iterator iterator = jo.keys();
        String xmlStr = "<xml>";
        while (iterator.hasNext()) {
            String key = (String) iterator.next();
            String val = jo.get(key).toString();
            xmlStr += "\n<" + key + ">" + val + "</" + key + ">";
        }
        return xmlStr + "\n</xml>";
    }

    /**
     * 方法用途: 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序），并且生成参数串<br>
     * 实现步骤: <br>
     *
     * @param paraMap    要排序的Map对象
     * @param urlEncode  是否需要URLENCODE
     * @param keyToLower 是否需要将Key转换为全小写
     *                   true:key转化成小写，false:不转化
     * @return
     */
    public static String formatUrlMap(Map<String, String> paraMap, boolean urlEncode, boolean keyToLower) {
        String buff = "";
        Map<String, String> tmpMap = paraMap;
        try {
            List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(tmpMap.entrySet());
            // 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序）
            Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {

                @Override
                public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                    return (o1.getKey()).toString().compareTo(o2.getKey());
                }
            });
            // 构造返回字符串键值对的格式
            StringBuilder buf = new StringBuilder();
            for (Map.Entry<String, String> item : infoIds) {
                if (item.getKey() != "") {
                    String key = item.getKey();
                    String val = item.getValue();
                    if (urlEncode) {
                        val = URLEncoder.encode(val, "utf-8");
                    }
                    if (keyToLower) {
                        buf.append(key.toLowerCase() + "=" + val);
                    } else {
                        buf.append(key + "=" + val);
                    }
                    buf.append("&");
                }

            }
            buff = buf.toString();
            if (buff.isEmpty() == false) {
                buff = buff.substring(0, buff.length() - 1);
            }
        } catch (Exception e) {
            return null;
        }
        return buff;
    }

    public static String getRandomString(int length) {

        //1. 定义一个字符串（A-Z，a-z，0-9）即62个数字字母；

        String str = "zxcvbnmlkjhgfdsaqwertyuiopQWERTYUIOPASDFGHJKLZXCVBNM1234567890";

        //2. 由Random生成随机数

        Random random = new Random();

        StringBuffer sb = new StringBuffer();

        //3. 长度为几就循环几次

        for (int i = 0; i < length; ++i) {

            //从62个的数字或字母中选择

            int number = random.nextInt(62);

            //将产生的数字通过length次承载到sb中

            sb.append(str.charAt(number));

        }
        //将承载的字符转换成字符串
        return sb.toString();
    }

}
